<?php
namespace App\Admin\Controllers\Stocking;

use App\Importer\Stocking\Sku\SkuImporter;
use App\Jobs\Stocking\Estimate;
use App\Jobs\Stocking\SkuRatio;
use App\Models\Basics\SysArea;
use App\Models\Basics\Transport;
use App\Models\Product\ProductClassify;
use App\Models\Product\ProductSku;
use App\Models\Shipping\SSku;
use App\Models\Shipping\SSkuApply;
use App\Models\SsBasic\AreaClassifyEstimate;
use App\Models\SsBasic\AreaSku;
use App\Models\SsBasic\AreaSkuEstimate;
use App\Models\Stocking\StockingSku;
use App\Models\Stocking\StockingSkuRatio;
use App\Util\RExcel;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Facades\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Illuminate\Support\Facades\DB;
class SkuUploadController extends AdminController{

    protected $title = '上传文件';

    protected function grid()
    {
        $type = request('type');
        return view("stocking.sku.upload.index",compact('type'));
    }

    public function upload(Request $request){
        $file = $request->file('source_file');
        if ($file->isValid()) {
            $action = $request->get('action');
            $re = $this->{'_import'.$action}($file);
            if(is_array($re)) {
                if($re['flag']){
                    admin_toastr('文件：'.$re['data'].' 上传成功！');
                }else{
                    admin_toastr($re['data'],'error');
                }
            }else{
                return $re;
            }
        }else{
            admin_toastr('无效文件！','error');
        }
        return back()->withInput();
    }

    private function _importNewSku(UploadedFile $file){
        try{
            $data = Excel::toArray(new SkuImporter(),$file);
            $data = $data[0];
            if(!$data)return ['flag' => false,'data' => '请上传包含有数据的文件！'];
            $errors = [];
            $count = 1;
            $arr = [];
            $skuArr = [];
            $pCycle = [];
            $price = [];
            $transportDayArr = [];
            foreach($data as $row){
                $count++;
                $_area = $row[0] ? trim($row[0]) : '';
                $sku = $row[1] ? trim($row[1]) : '';
                if(!$_area || !$sku){
                    $errors[$count] = '必填项为空';
                    continue;
                }
                $area = strtoupper($_area);
                $key = $area.'_'.$sku;
                if(!in_array($key,$arr)){
                    $arr[$count] = $key;
                }else{
                    $errors[$count] = '重复记录';
                    continue;
                }
                $areaId = SysArea::getSysAreaIdByArea($area);
                if(!$areaId){
                    $errors[$count] = $_area.'系统不存在';
                    continue;
                }
                if(!array_key_exists($sku,$skuArr)){
                    $_pSku = ProductSku::getModelByCode($sku);
                    $skuArr[$sku] = $_pSku ?: false;
                }
                if(!$skuArr[$sku]){
                    $errors[$count] = $sku.'系统不存在';
                    continue;
                }

                if ($areaId == 4) {
                    $errors[$count] = $_area.'备货(EU)站点功能已暂停，新功能迁移至《EU国家备货》，请前往使用！';
                    continue;
                }
                if ($areaId == 6) {
                    $errors[$count] = $_area.'备货(JP)站点功能已暂停，新功能迁移至《JP平台备货》，请前往使用！';
                    continue;
                }

                $pSku = $skuArr[$sku];
                $areaSkuKey = $areaId.'_'.$pSku->id;
                $reCount = AreaSku::query()->where('area_psku',$areaSkuKey)->count();
                if($reCount > 0){
                    $errors[$count] = $key.'系统已存在';
                    continue;
                }
                if(!array_key_exists($pSku->id,$price)){
                    $price[$pSku->id] = ProductSku::getPuPrice($pSku);
                }
                if(!array_key_exists($pSku->id,$pCycle)){
                    $pCycle[$pSku->id] = ProductSku::getPuCycle($pSku);
                }
                if(!array_key_exists($areaId,$transportDayArr)){
                    $_transportDay = Transport::getTransportDay($areaId);
                    $transportDayArr[$areaId] = $_transportDay ?: null;
                }
                $transportDay = $transportDayArr[$areaId];
                if($transportDay){
                    $airDay = $transportDay->air_day;
                    $seaDay = $transportDay->sea_day;
                }else{
                    $airDay = 0;
                    $seaDay = 0;
                }
                DB::beginTransaction();
                $as = AreaSku::query()->create(['area_psku' => $areaSkuKey,'type' => 2]);
                if(!$as){
                    DB::rollBack();
                    continue;
                }
                $ss = $as->stocking_sku()->create(
                    [
                        'area_id' => $areaId,
                        'psku_id' => $pSku->id,
                        'purchase_cycle' => $pCycle[$pSku->id],
                        'unit_price' => $price[$pSku->id],
                        'air_day' => $airDay,
                        'air_available' => AreaSku::getAvailable($pCycle[$pSku->id],$airDay),
                        'air_ship_factor' => AreaSku::getShipFactor($airDay),
                        'air_stock_factor' => AreaSku::getStockFactor($pCycle[$pSku->id],$airDay),
                        'sea_day' => $seaDay,
                        'sea_available' => AreaSku::getAvailable($pCycle[$pSku->id],$seaDay),
                        'sea_ship_factor' => AreaSku::getShipFactor($seaDay),
                        'sea_stock_factor' => AreaSku::getStockFactor($pCycle[$pSku->id],$seaDay),
                    ]
                );
                SSku::query()->updateOrCreate(
                    ['area_psku' => $areaSkuKey],
                    [
                        'area_id' => $areaId,
                        'psku_id' => $pSku->id,
                        'purchase_cycle' => $pCycle[$pSku->id],
                        'air_day' => $airDay,
                        'air_factor' => AreaSku::getSSkuFactor($pCycle[$pSku->id],$airDay),
                        'sea_day' => $seaDay,
                        'sea_factor' => AreaSku::getSSkuFactor($pCycle[$pSku->id],$seaDay),
                    ]
                );
                $shippingDate = SSkuApply::initShippingDate();
                foreach ($shippingDate as $date => $label){
                    $_ssaCount = SSkuApply::query()
                        ->where('area_id',$areaId)
                        ->where('psku_id',$pSku->id)
                        ->where('shipping_date',$date)
                        ->count();
                    if($_ssaCount == 0){
                        SSkuApply::query()->create(['area_id' => $areaId,'psku_id' => $pSku->id,'shipping_date' => $date]);
                    }
                }
                if($ss){
                    DB::commit();
                }else{
                    DB::rollBack();
                }
            }
            if(empty($errors)){
                return ['flag' => true,'data' => $file->getClientOriginalName()];
            }else{
                return RExcel::importResult($errors);
            }
        }catch(\Exception $e){
            DB::rollBack();
            report($e);
            return ['flag' => false,'data' => '系统异常！'];
        }
    }

    private function _importRatio(UploadedFile $file){
        try{
            $data = Excel::toArray(new SkuImporter(),$file);
            $data = $data[0];
            if(!$data)return ['flag' => false,'data' => '请上传包含有数据的文件！'];
            $errors = [];
            $count = 1;
            $arr = [];
            $item = [];
            foreach($data as $row){
                $count++;
                $_area = $row[0] ? trim($row[0]) : '';
                $sku = $row[1] ? trim($row[1]) : '';
                $_ratio = $row[2] ? trim($row[2]) : '';
                if(!$_area || !$sku){
                    $errors[$count] = '必填项为空';
                    continue;
                }
                $area = strtoupper($_area);
                $key = $area.'_'.$sku;
                if(!in_array($key,$arr)){
                    $arr[$count] = $key;
                }else{
                    $errors[$count] = '重复记录';
                    continue;
                }
                $areaId = SysArea::getSysAreaIdByArea($area);
                if(!$areaId){
                    $errors[$count] = $_area.'系统不存在';
                    continue;
                }
                if ($areaId == 4) {
                    $errors[$count] = $_area.'备货(EU)站点功能已暂停，新功能迁移至《EU国家备货》，请前往使用！';
                    continue;
                }
                if ($areaId == 6) {
                    $errors[$count] = $_area.'备货(JP)站点功能已暂停，新功能迁移至《JP平台备货》，请前往使用！';
                    continue;
                }
                $pSkuId = ProductSku::getValueByCode($sku,'id');
                if(!$pSkuId){
                    $errors[$count] = $sku.'系统不存在';
                    continue;
                }
                DB::beginTransaction();
                $ssr = StockingSkuRatio::query()->firstOrNew(['area_psku' => $areaId.'_'.$pSkuId]);
                $ssr->ratio = (float)$_ratio;
                $flag = $ssr->save();
                if($flag){
                    $item[] = $ssr;
                    DB::commit();
                }else{
                    DB::rollBack();
                }
            }
            if(!empty($item)){
                SkuRatio::dispatch($item);
            }
            if(empty($errors)){
                return ['flag' => true,'data' => $file->getClientOriginalName()];
            }else{
                return RExcel::importResult($errors);
            }
        }catch(\Exception $e){
            report($e);
            return ['flag' => false,'data' => '系统异常！'];
        }
    }

    private function _importEstimate(UploadedFile $file){
        try{
            $data = Excel::toArray(new SkuImporter(),$file);
            $data = $data[0];
            if(!$data)return ['flag' => false,'data' => '请上传包含有数据的文件！'];
            $errors = [];
            $count = 1;
            $arr = [];
            $item = [];
            foreach($data as $row){
                $count++;
                $_area = $row[0] ? trim($row[0]) : '';
                $classify = $row[1] ? trim($row[1]) : '';
                $j = 2;
                for($i = 0; $i < AreaSkuEstimate::ESTIMATE_NUM; $i++){
                    ${'estimate_num'.$i} = is_null($row[$j]) ? null : trim($row[$j]);
                    $j++;
                }
                if(!$_area || !$classify){
                    $errors[$count] = '必填项为空';
                    continue;
                }
                $area = strtoupper($_area);
                $key = $area.'_'.$classify;
                if(!in_array($key,$arr)){
                    $arr[$count] = $key;
                }else{
                    $errors[$count] = '重复记录';
                    continue;
                }
                $areaId = SysArea::getSysAreaIdByArea($area);
                if(!$areaId){
                    $errors[$count] = $_area.'系统不存在';
                    continue;
                }
                if ($areaId == 4) {
                    $errors[$count] = $_area.'备货(EU)站点功能已暂停，新功能迁移至《EU国家备货》，请前往使用！';
                    continue;
                }
                if ($areaId == 6) {
                    $errors[$count] = $_area.'备货(JP)站点功能已暂停，新功能迁移至《JP平台备货》，请前往使用！';
                    continue;
                }
                $classifyId = ProductClassify::getIdByTitle($classify);
                if(!$classifyId){
                    $errors[$count] = $classify.'系统不存在';
                    continue;
                }
                DB::beginTransaction();
                $acEstimate = AreaClassifyEstimate::query()->firstOrNew(['area_id' => $areaId,'classify_id' => $classifyId]);
                for($i = 0; $i < AreaSkuEstimate::ESTIMATE_NUM; $i++){
                    if(!is_null(${'estimate_num'.$i})){
                        $acEstimate->{'estimate_num'.$i} = ${'estimate_num'.$i};
                    }
                }
                $flag = $acEstimate->save();
                if($flag){
                    $item[] = $acEstimate;
                    DB::commit();
                }else{
                    DB::rollBack();
                }
            }
            if(!empty($item)){
                Estimate::dispatch($item);
            }
            if(empty($errors)){
                return ['flag' => true,'data' => $file->getClientOriginalName()];
            }else{
                return RExcel::importResult($errors);
            }
        }catch(\Exception $e){
            DB::rollBack();
            report($e);
            return ['flag' => false,'data' => '系统异常！'];
        }
    }

    private function _importApply(UploadedFile $file){
        try{
            $data = Excel::toArray(new SkuImporter(),$file);
            $data = $data[0];
            if(!$data)return ['flag' => false,'data' => '请上传包含有数据的文件！'];
            DB::beginTransaction();
            $errors = [];
            $count = 1;
            $arr = [];
            $userId = Admin::user()->id;
            foreach($data as $row){
                $count++;
                $_area = $row[0] ? trim($row[0]) : '';
                $sku = $row[1] ? trim($row[1]) : '';
                $applyNum = $row[2] ? trim($row[2]) : 0;
                $applyRemark = $row[3] ? trim($row[3]) : '';
                if(!$_area || !$sku){
                    $errors[$count] = '必填项为空';
                    continue;
                }
                $area = strtoupper($_area);
                $key = $area.'_'.$sku;
                if(!in_array($key,$arr)){
                    $arr[$count] = $key;
                }else{
                    $errors[$count] = '重复记录';
                    continue;
                }
                if(!is_numeric($applyNum)){
                    $errors[$count] = '备货数量格式有误';
                    continue;
                }
                if($applyNum < 0){
                    $errors[$count] = '备货数量不能小于0';
                    continue;
                }
                $areaId = SysArea::getSysAreaIdByArea($area);
                if(!$areaId){
                    $errors[$count] = $_area.'系统不存在还站点';
                    continue;
                }
                //if ($areaId == 4) {
                //    $errors[$count] = $_area.'备货(EU)站点功能已暂停，新功能迁移至《EU国家备货》，请前往使用！';
                //    continue;
                //}
                //if ($areaId == 6) {
                //    $errors[$count] = $_area.'备货(JP)站点功能已暂停，新功能迁移至《JP平台备货》，请前往使用！';
                //    continue;
                //}
                $pSkuId = ProductSku::getValueByCode($sku,'id');
                if(!$pSkuId){
                    $errors[$count] = $sku.'系统不存在该sku';
                    continue;
                }
                $ss = StockingSku::query()->where('area_id',$areaId)->where('psku_id',$pSkuId)->first();
                if(!$ss){
                    $errors[$count] = $key.'系统不存在该备货';
                    continue;
                }
                if($ss->status == 2){
                    $errors[$count] = $key.'审批中勿修改';
                    continue;
                }
                $ss->seller_id = $userId;
                $ss->apply_num = $applyNum;
                $ss->approval_num = $applyNum;
                $ss->status = 2;
                if($applyRemark){
                    $ss->apply_remark = $applyRemark;
                }
                $ss->save();
            }
            DB::commit();
            if(empty($errors)){
                return ['flag' => true,'data' => $file->getClientOriginalName()];
            }else{
                return RExcel::importResult($errors);
            }
        }catch(\Exception $e){
            DB::rollBack();
            report($e);
            return ['flag' => false,'data' => '系统异常！'];
        }
    }

    public function template(Request $request){
        $temp = $request->get('temp');
        $suffix = $request->get('suffix','xlsx');
        return Storage::disk('admin')->download("template/{$temp}-template.{$suffix}");
    }
}
